home *** CD-ROM | disk | FTP | other *** search
/ Programming an RTS Game with Direct3D / Programming an RTS Game with Direct3D.iso / Examples / Chapter 16 / Example 16.1 / sound.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2006-06-30  |  5.2 KB  |  231 lines

  1. #include "sound.h"
  2.  
  3. //////////////////////////////////////////////////////////////
  4. //                    SOUNDFILE                                //
  5. //////////////////////////////////////////////////////////////
  6.  
  7. SOUNDFILE::SOUNDFILE()
  8. {
  9.     m_pSegment = NULL;
  10. }
  11.  
  12. SOUNDFILE::~SOUNDFILE()
  13. {
  14.     if(m_pSegment)
  15.         m_pSegment->Release();
  16.     m_pSegment = NULL;
  17. }
  18.  
  19. void SOUNDFILE::Load(WCHAR fileName[], SOUND &sound)
  20. {
  21.     //Create new segment 
  22.     CoCreateInstance(CLSID_DirectMusicSegment, NULL,
  23.                      CLSCTX_INPROC, IID_IDirectMusicSegment8,
  24.                      (void**)&m_pSegment);
  25.  
  26.     //Load from file using the loader
  27.     sound.m_pLoader->LoadObjectFromFile(CLSID_DirectMusicSegment, 
  28.                                      IID_IDirectMusicSegment8, 
  29.                                      fileName, (void**)&m_pSegment);
  30.  
  31.     //Download sound to the performance interface
  32.     m_pSegment->Download(sound.m_pPerformance);
  33. }
  34.  
  35. //////////////////////////////////////////////////////////////
  36. //                    SOUND                                    //
  37. //////////////////////////////////////////////////////////////
  38.  
  39. SOUND::SOUND()
  40. {
  41.     m_pPerformance = NULL;
  42.     m_pLoader = NULL;
  43. }
  44.  
  45. SOUND::~SOUND()
  46. {
  47.     //Delete sound files
  48.     for(int i=0;i<m_sounds.size();i++)
  49.         if(m_sounds[i] != NULL)
  50.             delete m_sounds[i];
  51.     m_sounds.clear();
  52.  
  53.     //Release the loader and the performance
  54.     if(m_pLoader)
  55.         m_pLoader->Release();
  56.     m_pLoader = NULL;
  57.  
  58.     if(m_pPerformance)
  59.     {
  60.         m_pPerformance->CloseDown();
  61.         m_pPerformance->Release();
  62.     }
  63.     m_pPerformance = NULL;
  64. }
  65.  
  66. void SOUND::Init(HWND windowHandle)
  67. {
  68.     CoInitialize(NULL);
  69.  
  70.     //Create performance object
  71.     CoCreateInstance(CLSID_DirectMusicPerformance, NULL, CLSCTX_INPROC,
  72.                      IID_IDirectMusicPerformance8, (void**)&m_pPerformance);
  73.  
  74.     //Create loader
  75.     CoCreateInstance(CLSID_DirectMusicLoader, NULL, CLSCTX_INPROC, 
  76.                      IID_IDirectMusicLoader8, (void**)&m_pLoader);
  77.  
  78.     //Initialize the performance object
  79.     m_pPerformance->InitAudio(NULL, NULL, windowHandle, 
  80.                            DMUS_APATH_SHARED_STEREOPLUSREVERB, 
  81.                            64, DMUS_AUDIOF_ALL, NULL);
  82.  
  83.     //Load sound files
  84.     std::vector<WCHAR*> fileNames;
  85.  
  86.     //fileNames.push_back(L"SoundFile.wav");
  87.  
  88.     for(int i=0;i<fileNames.size();i++)
  89.     {
  90.         SOUNDFILE *snd = new SOUNDFILE();
  91.         snd->Load(fileNames[i], *this);
  92.         m_sounds.push_back(snd);
  93.     }
  94.  
  95.     SetMasterVolume(0.75f);    
  96. }    
  97.  
  98. void SOUND::PlaySound(int soundID, bool loop)
  99. {
  100.     //Faulty Sound ID
  101.     if(soundID < 0 || soundID >= m_sounds.size())return;
  102.  
  103.     //Loop sound or not
  104.     if(loop)
  105.         m_sounds[soundID]->m_pSegment->SetRepeats(DMUS_SEG_REPEAT_INFINITE);
  106.     else m_sounds[soundID]->m_pSegment->SetRepeats(0);
  107.  
  108.     //Play Sound
  109.     m_pPerformance->PlaySegment(m_sounds[soundID]->m_pSegment, DMUS_SEGF_SECONDARY, 0, NULL);
  110. }
  111.  
  112. void SOUND::SetMasterVolume(float volume)
  113. {
  114.     //Cap volume to the range [0.0, 1.0]
  115.     if(volume < 0.0f)volume = 0.0f;
  116.     if(volume > 1.0f)volume = 1.0f;
  117.     m_masterVolume = volume;
  118.  
  119.     //Translate to the decibel range [-500, -4000]
  120.     long vol = -3500 * (1.0f - sqrt(volume)) - 500;
  121.  
  122.     //Set master volume
  123.     if(m_pPerformance)
  124.         m_pPerformance->SetGlobalParam(GUID_PerfMasterVolume, (void*)&vol, sizeof(long)); 
  125. }
  126.  
  127. //////////////////////////////////////////////////////////////
  128. //                    MP3PLAYER                                //
  129. //////////////////////////////////////////////////////////////
  130.  
  131. MP3::MP3()
  132. {
  133.     m_pGraphBuilder = NULL;
  134.     m_pMediaControl = NULL;
  135.     m_pMediaPosition = NULL;
  136.     m_pBasicAudio = NULL;
  137. }
  138.  
  139. MP3::~MP3()
  140. {
  141.     Release();
  142. }
  143.  
  144. void MP3::Release()
  145. {
  146.     if(m_pBasicAudio)m_pBasicAudio->Release();
  147.     if(m_pMediaPosition)m_pMediaPosition->Release();
  148.     if(m_pMediaControl)m_pMediaControl->Release();
  149.     if(m_pGraphBuilder)m_pGraphBuilder->Release();
  150.  
  151.     m_pGraphBuilder = NULL;
  152.     m_pMediaControl = NULL;
  153.     m_pMediaPosition = NULL;
  154.     m_pBasicAudio = NULL;
  155. }
  156.  
  157. void MP3::Init()
  158. {
  159.     Release();
  160.  
  161.     // Initialise COM
  162.     CoInitialize(NULL);
  163.  
  164.     // Create the Filter Graph Manager
  165.     CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
  166.                       IID_IGraphBuilder, (void **)&m_pGraphBuilder);
  167.  
  168.     m_pGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&m_pMediaControl);
  169.     m_pGraphBuilder->QueryInterface(IID_IMediaPosition, (void**)&m_pMediaPosition);
  170.     m_pGraphBuilder->QueryInterface(IID_IBasicAudio, (void **)&m_pBasicAudio);
  171. }
  172.  
  173. void MP3::LoadSong(WCHAR fName[])
  174. {
  175.     //Init the DirectShow objects
  176.     Init();        
  177.  
  178.     //Create standard graph
  179.     m_pGraphBuilder->RenderFile(fName, NULL);
  180. }
  181.  
  182. void MP3::Play()
  183. {
  184.     //rewind...
  185.     m_pMediaPosition->put_CurrentPosition(0);
  186.  
  187.     //Play
  188.     m_pMediaControl->Run();
  189. }
  190.  
  191. void MP3::Stop()
  192. {
  193.     m_pMediaControl->Stop();
  194. }
  195.  
  196. bool MP3::IsPlaying()
  197. {
  198.     REFTIME currentPos;
  199.     REFTIME duration;
  200.  
  201.     m_pMediaPosition->get_CurrentPosition(¤tPos);
  202.     m_pMediaPosition->get_Duration(&duration);
  203.     
  204.     if(currentPos < duration)
  205.         return true;
  206.     else return false;
  207. }
  208.  
  209. void MP3::SetVolume(float volume)
  210. {
  211.     if(volume < 0.0f)volume = 0.0f;
  212.     if(volume > 1.0f)volume = 1.0f;
  213.     
  214.     if(m_pBasicAudio)
  215.     {
  216.         long vol = -10000 * (1.0f - sqrt(volume));
  217.         m_pBasicAudio->put_Volume(vol);
  218.     }
  219. }
  220.  
  221. void MP3::SetBalance(float balance)
  222. {
  223.     if(balance < -1.0f)balance = -1.0f;
  224.     if(balance > 1.0f)balance = 1.0f;
  225.  
  226.     if (m_pBasicAudio)
  227.     {
  228.         float bal = 10000 * balance;
  229.         m_pBasicAudio->put_Balance(bal);
  230.     }
  231. }